<?php
namespace app\common\model\direct;
use app\admin\model\Third;
use app\common\model\meet\Config;
use app\common\model\meet\Store;
use app\common\model\User;
use EasyWeChat\Factory;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use think\Model;

class OrderModel  extends Model
{
    protected $name="direct_order";
    private $err;
    const STATUS_CREATE = 0;
    const STATUS_PAYED = 1;
    const STATUS_DELETE = 2;
    public function getStatusCh($v){
        switch ($v){
            case OrderModel::STATUS_CREATE:return '未支付';
            case OrderModel::STATUS_PAYED:return '已支付';
            case OrderModel::STATUS_DELETE:return '已删除';
            default:return "未知";
        }
    }
    /**
     * @return mixed
     */
    public function getErr()
    {
        return $this->err;
    }
    public function creator(){
       return  $this->hasOne(User::class,"id","create_uid");
    }
    public function beyond(){
       return  $this->hasOne(User::class,"id","user_id");
    }
    public function store(){
        return  $this->hasOne(Store::class,"id","store_id");
    }
    /**
     * @param mixed $err
     */
    public function setErr($err): void
    {
        $this->err = $err;
    }
    public function createOrderNo()
    {
        return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }
    public function createOne($storeId,$amount,$userId,$createUid,$remark=""){
        if (!$storeId){
            $this->setErr('必须提供门店');
            return false;
        }
        if (!$userId){
            $this->setErr('用户标识丢失');
            return false;
        }
        if (!$amount||$amount<0){
            $this->setErr('不能是0元');
            return false;
        }
        $data['order_no'] = $this->createOrderNo();
        $data['store_id'] = $storeId;
        $data['user_id'] = $userId;
        $data['create_uid'] = $createUid;
        $data['create_time'] = time();
        $data['update_time'] = time();
        $data['amount'] = $amount;
        $data['sign'] = $this->createSign($data);
        $data['remark'] = $remark;
        return $this->insert($data,false,true);
    }

    private function createSign($data)
    {
        ksort($data);
        return sha1(implode("",array_map(function($item){
            return "010".$item."101";
        },$data)));
    }
    public function checkSign($orderId){
        $order=$this->find($orderId);
        if (!$order){
            $this->setErr("订单不存在");
            return false;
        }else{
            return $this->createSign([
                'order_no'=>$order['order_no'],
                'store_id'=>$order['store_id'],
                'user_id'=>$order['user_id'],
                'create_uid'=>$order['create_uid'],
                'amount'=>$order['amount']
                ])==$order['sign'];
        }
    }

    public function payOrder($orderId, string $notify_url)
    {
        $order=$this->find($orderId);
        if (!$order) {
            $this->setErr("订单不存在");
            return false;
        }
        if ($order['status']!=$this::STATUS_CREATE){
            $this->setErr("订单状态不对");
            return false;
        }


        try {
            $config = Config::getPayConfig();
            $config['notify_url'] = $notify_url;
            $app = Factory::payment($config);
            $openid = Third::where('user_id', '=', $order->user_id)->value('openid');
            if (!$openid)throw new Exception('没有绑定微信账户');

            $response = $app->order->unify([
                'body' => $order['order_no'],
                'out_trade_no' => $order['order_no'],
                'total_fee' => $order['amount'] * 100,
                //'total_fee' => $order['amount'],
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => $openid,
                'notify_url' => $notify_url
            ]);

            //调用支付失败
            if ($response["return_code"] === 'FAIL') {
                throw new Exception($response["return_msg"]);
            }

            if ($response["result_code"] === 'FAIL') {
                throw new Exception($response["err_code_des"]);
            }
            return $app->jssdk->bridgeConfig($response['prepay_id'], false);
//            //计划任务-取消订单
//            $auto_close = Config::getConfigByName('meet_order_auto_close')['value'];
//            $cronLogic = new Cron();
//            $cronLogic->addCron('预约-取消订单', 'CronMeetOrderCancel', time() + (($auto_close ?: 5) * 60), $order['id']);

        } catch (\Exception $e) {
            $this->setErr($e->getMessage());
            return false;
        } catch (GuzzleException $e) {
            $this->setErr($e->getMessage());
            return false;
        }
    }
}